<!--
  - Copyright (c) 2023.
  -
  - 作者：bmy
  - 邮箱：2271608011@qq.com
  - gitee：https://gitee.com/bmycode
  - github：https://github.com/helpcode
  -
  -->

<script lang="ts">
  import { onDestroy, onMount } from "svelte";
  import { MonacoEditor } from "@/utils/MonacoEditor";
  import config from "@/config";
  import { toClass } from "json-class-interface";
  import { themeConfig } from '@/stores/ThemeStore';
  import { ToClassOptions } from "json-class-interface/dist/typing";
  import Notification from "@/utils/Notification";
  import { invoke } from "@tauri-apps/api/primitives";
  import { writeText } from '@tauri-apps/plugin-clipboard-manager';

  let JsonDom: HTMLElement;
  let ClassOrInterfaceDom: HTMLElement;
  let unlisten;

  onMount(() => {
    initEdit()
    initResized()
  });

  /**
   * 窗口尺寸变化时候，重新计算 编辑器 的两个宽高
   */
  const initResized = async () => {
    unlisten = await config.appWindow.onResized(({ payload: size }) => {
      let reSize = size
      reSize.width = reSize.width / 2 / 2 - 105
      reSize.height = reSize.height / 2 / 2 - 35
      config.Json.layout(reSize)
      config.ClassOrInterface.layout(reSize)
    })
  }

  const initEdit = () => {
    // 创建两个编辑器
    config.Json = MonacoEditor.creatMonacoEditor(JsonDom)
    config.ClassOrInterface = MonacoEditor.creatMonacoEditor(ClassOrInterfaceDom)

    // 对json编辑器输入内容进行监听
    config.Json.onDidChangeModelContent(async e => {
      if (config.Json.getValue().length != 0) {

        // 使用本地存储的 toClass 配置
        let toClassOptions: ToClassOptions = {
          nullAlias        : $themeConfig.nullAlias,
          needProperty     : Boolean($themeConfig.needProperty),
          needPropertyValue: Boolean($themeConfig.needPropertyValue),
          interfaceModel   : Boolean($themeConfig.JsonType)
        }

        // 如果设置文件名，那么第一层类名或接口名使用文件名，否则使用默认
        let className: string =
          $themeConfig.saveFileName.length != 0
            ? $themeConfig.saveFileName
            : Boolean($themeConfig.JsonType)
              ? 'JsonToInterface'
              : 'JsonToClass'

        let Result: string = toClass(className, config.Json.getValue(), toClassOptions)
        Result = autoImport(Result)

        config.ClassOrInterface.setValue(Result)
        await isAutoClipboard(Result)
        await isAutoSave(Result)

      } else {
        config.ClassOrInterface.setValue("")
      }
    })
  }

  /**
   * 是否自动复制到粘贴板
   * @param Result
   */
  const isAutoClipboard = async (Result: string) => {
    if ($themeConfig.autoClipboard) {
      // 将内容粘贴到你的剪贴板
      await writeText(Result);
      await Notification.send({
        title: '提示',
        body: '代码已粘贴到剪贴板，Ctrl + V 使用吧'
      })
    }
  }

  /**
   * 如果是类，自动导包，如果开启 needProperty，自动导入 property 装饰器
   * @param Result
   */
  const autoImport = (Result: string): string => {

    if (!$themeConfig.JsonType) {
      Result =`import { toClass${$themeConfig.needProperty ? ', property ' : ''} } from 'json-mapper-class';
${Result}`
    }
    return Result
  }

  /**
   * 如果开启 自动存储 ，那么存储文件到路径
   * @param Result
   */
  const isAutoSave = async (Result: string) => {
    if ($themeConfig.autoSave) {
      // 调用 rust 封装的方法，进行文件存储
      await invoke("created_file", {
        name: `${$themeConfig.savePath}/${$themeConfig.saveFileName}.ts`,
        content: Result
      });

      await Notification.send({
        title: '提示',
        body: `${$themeConfig.saveFileName}.ts 已保存在 ${$themeConfig.savePath}`
      })
    }
  }

  onDestroy(() => {
    unlisten()
  })

</script>

<div class="edit">
    <div class="json" bind:this={JsonDom}></div>
    <div class="interface" bind:this={ClassOrInterfaceDom}></div>
</div>

<style lang="less">
  .edit {
    display: flex;
    height: 100%;

    .json,
    .interface {
      height: 100%;
      flex: 1;
    }

    .json {
    }

    .interface {
    }
  }
</style>